/** @file

Copyright (c) 2006-2023, Kunlun BIOS, Kunlun Technology (Beijing) Co., Ltd.. All
Rights Reserved.

You may not reproduce, distribute, publish, display, perform, modify, adapt,
transmit, broadcast, present, recite, release, license or otherwise exploit
any part of this publication in any form, by any means, without the prior
written permission of Kunlun Technology (Beijing) Co., Ltd..

Module Name:


Abstract:


Revision History:

**/

#include <Library/DisplayPictureLib.h>

UINT32                          GraphicsMode = 0;
UINT32                          SizeOfX = 0;
UINT32                          SizeOfY = 0;
UINT32                          ColorDepth = 0;
UINT32                          RefreshRate = 0;

/**
  This function restores the Graphics Screen from the variable.

  @param[in]   Blt        a pointer to void.

**/
EFI_STATUS
SetPopUpBackground(
  VOID   **Blt
)
{
  EFI_STATUS                          Status;
  EFI_GRAPHICS_OUTPUT_PROTOCOL        *GraphicsOutput;
  EFI_UGA_DRAW_PROTOCOL               *UgaDraw;

  GraphicsOutput = NULL;
  UgaDraw = NULL;


  if (*Blt == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Try to open GOP first
  //
  Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
    GraphicsOutput = NULL;
    //
    // Open GOP failed, try to open UGA
    //
    Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
    if (EFI_ERROR (Status)) {
      UgaDraw = NULL;
    }
  }
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  if (GraphicsOutput != NULL) {
    //Status = GraphicsOutput->SetMode(GraphicsOutput, GraphicsMode); // Mask this code, because of not need clean the screen before recover the background
    DEBUG ((DEBUG_INFO, "%a(): GraphicsOutput SetMode(%r)\n", __FUNCTION__, Status));
    DEBUG ((DEBUG_INFO, "%a(): %d %d %d\n", __FUNCTION__,  SizeOfX,SizeOfY,GraphicsMode));
    if (EFI_ERROR (Status)) {
      return Status;
    }
    Status = GraphicsOutput->Blt(
                              GraphicsOutput,
                              (EFI_GRAPHICS_OUTPUT_BLT_PIXEL*)(*Blt),
                              EfiBltBufferToVideo,
                              0,
                              0,
                              0,
                              0,
                              SizeOfX,
                              SizeOfY,
                              0
                              );
    DEBUG ((DEBUG_INFO, "%a(): GraphicsOutput(%r)\n", __FUNCTION__,  Status));
    if (EFI_ERROR(Status)) {
      gBS->FreePool(*Blt);
      *Blt = NULL;
    }
  } else if (UgaDraw != NULL){
    Status = UgaDraw->SetMode (UgaDraw, SizeOfX, SizeOfY, ColorDepth, RefreshRate);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    Status = UgaDraw->Blt(
                       UgaDraw,
                       (EFI_UGA_PIXEL*)(*Blt),
                       EfiUgaBltBufferToVideo,
                       0,
                       0,
                       0,
                       0,
                       SizeOfX,
                       SizeOfY,
                       0
                       );
      DEBUG ((DEBUG_INFO, "%a(): UgaDraw(%r)\n", __FUNCTION__,  Status));
      if (EFI_ERROR(Status)) {
        gBS->FreePool(*Blt);
        *Blt = NULL;
    }
  } else {
    Status = EFI_UNSUPPORTED;
  }

  return Status;
}

/**
    This function dumps the current graphics screen to variable.

    @param[in]   Blt        a pointer to void.

**/
EFI_STATUS
GetPopUpBackground(
  VOID   **Blt
)
{
  EFI_STATUS                          Status;
  EFI_GRAPHICS_OUTPUT_PROTOCOL        *GraphicsOutput;
  EFI_UGA_DRAW_PROTOCOL               *UgaDraw;

  GraphicsOutput = NULL;
  UgaDraw = NULL;


  if (*Blt != NULL) {
    gBS->FreePool(*Blt);
  }

  //
  // Try to open GOP first
  //
  Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput);
  if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) {
    GraphicsOutput = NULL;
    //
    // Open GOP failed, try to open UGA
    //
    Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw);
    if (EFI_ERROR (Status)) {
      UgaDraw = NULL;
    }
  }

  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  if (GraphicsOutput != NULL) {
    SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution;
    SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution;
    GraphicsMode = GraphicsOutput->Mode->Mode;
    DEBUG ((DEBUG_INFO, "%a(): %d %d %d\n", __FUNCTION__,  SizeOfX,SizeOfY,GraphicsMode));
  } else {
    ASSERT (UgaDraw != NULL);
    Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate);
    if (EFI_ERROR (Status)) {
      return EFI_UNSUPPORTED;
    }
  }

  if (GraphicsOutput != NULL) {
    *Blt = AllocateZeroPool (SizeOfX * SizeOfY * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
    if (*Blt != NULL) {
      Status = GraphicsOutput->Blt(
                                GraphicsOutput,
                                (EFI_GRAPHICS_OUTPUT_BLT_PIXEL*)(*Blt),
                                EfiBltVideoToBltBuffer,
                                0,
                                0,
                                0,
                                0,
                                SizeOfX,
                                SizeOfY,
                                0
                                );
      DEBUG ((DEBUG_INFO, "%a(): GraphicsOutput(%r)\n", __FUNCTION__,  Status));
      if (EFI_ERROR(Status)) {
        gBS->FreePool(*Blt);
        *Blt = NULL;
      }
    }
  } else if (UgaDraw != NULL){
    *Blt = AllocateZeroPool (SizeOfX * SizeOfY * sizeof (EFI_UGA_PIXEL));
    if (*Blt != NULL) {
      Status = UgaDraw->Blt(
                         UgaDraw,
                         (EFI_UGA_PIXEL*)(*Blt),
                         EfiUgaVideoToBltBuffer,
                         0,
                         0,
                         0,
                         0,
                         SizeOfX,
                         SizeOfY,
                         0
                         );
      DEBUG ((DEBUG_INFO, "%a(): UgaDraw(%r)\n", __FUNCTION__,  Status));
      if (EFI_ERROR(Status)) {
        gBS->FreePool(*Blt);
        *Blt = NULL;
      }
    }
  } else {
    Status = EFI_UNSUPPORTED;
  }

  return Status;
}
